package cn.flying.system.service.cm.impl;

import javax.annotation.Resource;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import cn.flying.base.common.vo.TreeSelectInfo;
import cn.flying.base.common.vo.XmSelect;
import cn.flying.system.common.enums.SeqTypeEnum;
import cn.flying.system.common.vo.OrgTreeTableInfo;
import cn.flying.system.domain.cm.CmOrganization;
import cn.flying.system.domain.cm.CmOrganizationExample;
import cn.flying.system.mapper.cm.CmOrganizationMapper;
import cn.flying.system.service.cm.CmOrganizationService;
import cn.flying.system.service.cm.CmSeqService;

/**
 * @description:
 * @author: lvyong
 * @date: 2022年05月26日 22:40
 * @version: 1.0
 */
@Service
public class CmOrganizationServiceImpl implements CmOrganizationService {

    @Resource
    private CmOrganizationMapper cmOrganizationMapper;
    @Autowired
    private CmSeqService cmSeqService;

    /**
     * 获取组织机构tree数据
     *
     * @return
     */
    @Override
    public List<OrgTreeTableInfo> getOrganizationTreeTableList() {
        CmOrganizationExample example = new CmOrganizationExample();
        CmOrganizationExample.Criteria criteria = example.createCriteria();
        example.setOrderByClause(" org_id asc ");
        List<CmOrganization> organizations = cmOrganizationMapper.selectByExample(example);

        //从根节点开始
        List<OrgTreeTableInfo> treeTableInfos = convertOrganizationToTreeTableInfo(organizations);

        List<OrgTreeTableInfo> tableInfos = setChildren(treeTableInfos, "root");

        return tableInfos;
    }

    private List<OrgTreeTableInfo> convertOrganizationToTreeTableInfo(List<CmOrganization> list) {
        return list.stream().map(m -> {
            OrgTreeTableInfo tableInfo = new OrgTreeTableInfo();
            tableInfo.setId(m.getId());
            tableInfo.setOrgId(m.getOrgId());
            tableInfo.setOrgName(m.getOrgName());
            tableInfo.setParentId(m.getParentId());
            tableInfo.setParentName(m.getParentName());
            tableInfo.setOrgLevel(m.getOrgLevel());
            tableInfo.setOrgType(m.getOrgType());
            tableInfo.setOrgPath(m.getOrgPath());
            tableInfo.setPhone(m.getPhone());
            tableInfo.setOrgAddress(m.getOrgAddress());
            tableInfo.setExt1(m.getExt1());
            tableInfo.setExt2(m.getExt2());
            tableInfo.setExt3(m.getExt3());
            tableInfo.setRemark(m.getRemark());
            tableInfo.setTenantId(m.getTenantId());
            tableInfo.setUpdatedBy(m.getUpdatedBy());
            tableInfo.setUpdatedTime(m.getUpdatedTime());
            return tableInfo;
        }).collect(Collectors.toList());
    }

    private List<OrgTreeTableInfo> setChildren(List<OrgTreeTableInfo> list, String parentId) {
        List<OrgTreeTableInfo> tableInfos = list.stream()
                // 过滤父节点
                .filter(parent -> parentId.equals(parent.getParentId()))
                // 递归赋值children
                .map(child -> {
                    List<OrgTreeTableInfo> temp = setChildren(list, child.getOrgId());
                    if (CollectionUtils.isEmpty(temp)) {
                        child.setChildren(new ArrayList<>());
                        child.setParent(false);
                    } else {
                        child.setChildren(temp);
                        child.setParent(true);
                    }
                    return child;
                })
                .collect(Collectors.toList());
        return tableInfos;
    }

    /**
     * 组织结构树形下拉
     *
     * @return
     */
    @Override
    public List<TreeSelectInfo> getOrganizationTree() {
        CmOrganizationExample example = new CmOrganizationExample();
        CmOrganizationExample.Criteria criteria = example.createCriteria();
//        criteria.andTypeEqualTo(OrganizationsTypeEnum.PERMISSIONS_TYPE_MENU.getType());
//        List<String> stringList = new ArrayList<>();
//        stringList.add(OrganizationsTypeEnum.PERMISSIONS_TYPE_MENU.getType());
//        stringList.add(OrganizationsTypeEnum.PERMISSIONS_TYPE_SYS.getType());
//        criteria.andTypeIn(stringList);
        //获取菜单
        List<CmOrganization> menuList = cmOrganizationMapper.selectByExample(example);

        List<TreeSelectInfo> treeSelectInfos = menuList.stream().map(m -> {
            TreeSelectInfo treeSelectInfo = new TreeSelectInfo();
            treeSelectInfo.setId(m.getOrgId());
            treeSelectInfo.setPid(m.getParentId());
            treeSelectInfo.setName(m.getOrgName());
            treeSelectInfo.setOpen(false);
            treeSelectInfo.setChecked(false);
            return treeSelectInfo;
        }).collect(Collectors.toList());

        List<TreeSelectInfo> infos = streamToTree(treeSelectInfos, "0");

        for (TreeSelectInfo info : infos) {
            if (!CollectionUtils.isEmpty(info.getChildren())) {
                info.setOpen(true);
            }
        }

        return infos;
    }

    private List<TreeSelectInfo> streamToTree(List<TreeSelectInfo> treeList, String parentId) {
        List list = treeList.stream()
                // 过滤父节点
                .filter(parent -> parent.getPid().equals(parentId))
                // 把父节点children递归赋值成为子节点
                .map(child -> {
                    List<TreeSelectInfo> temp = streamToTree(treeList, child.getId());
                    if (!CollectionUtils.isEmpty(temp)) {
                        child.setChildren(temp);
                    }
                    return child;
                }).collect(Collectors.toList());
        return list;
    }

    /**
     * 组织结构下拉
     *
     * @return
     */
    @Override
    public List<XmSelect> getOrganizationSelectList() {
        CmOrganizationExample example = new CmOrganizationExample();
        CmOrganizationExample.Criteria criteria = example.createCriteria();
        //获取组织
        List<CmOrganization> organizations = cmOrganizationMapper.selectByExample(example);

        List<XmSelect> xmSelects = organizations.stream().map(m -> {
            XmSelect xmSelect = new XmSelect();
            xmSelect.setValue(m.getOrgId());
            xmSelect.setName(m.getOrgName());
            xmSelect.setPid(m.getParentId());
            xmSelect.setDisabled(false);
            xmSelect.setSelected(false);
            return xmSelect;
        }).collect(Collectors.toList());

        List<XmSelect> infos = listToTree(xmSelects, "root");

        return infos;
    }

    private List<XmSelect> listToTree(List<XmSelect> treeList, String parentId) {
        List list = treeList.stream()
                // 过滤父节点
                .filter(parent -> parent.getPid().equals(parentId))
                // 把父节点children递归赋值成为子节点
                .map(child -> {
                    List<XmSelect> temp = listToTree(treeList, child.getValue());
                    child.setChildren(temp);
                    return child;
                }).collect(Collectors.toList());
        return list;
    }

    /**
     * 根据主键id查询
     *
     * @param id
     * @return
     */
    @Override
    public CmOrganization getOrganizationById(Long id) {
        return cmOrganizationMapper.selectByPrimaryKey(id);
    }

    /**
     * 根据组织编码查询
     *
     * @param orgId
     * @return
     */
    @Override
    public CmOrganization getOrganizationByOrgCode(String orgId) {
        CmOrganizationExample example = new CmOrganizationExample();
        CmOrganizationExample.Criteria criteria = example.createCriteria();
        criteria.andOrgIdEqualTo(orgId);
        List<CmOrganization> organizations = cmOrganizationMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(organizations)) {
            return new CmOrganization();
        }
        return organizations.get(0);
    }

    /**
     * 新增保存
     *
     * @param organization
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void insertOrganization(CmOrganization organization) {
        if (StringUtils.isEmpty(organization.getId())) {
            String seq = cmSeqService.getSeq(SeqTypeEnum.DEPT.name());
            organization.setOrgId(seq);
        }
        CmOrganization parent = this.getOrganizationByOrgCode(organization.getParentId());
        organization.setOrgPath(parent.getOrgPath() + organization.getOrgId() + "/");
        cmOrganizationMapper.insertSelective(organization);
    }

    /**
     * 通过主键Id修改
     *
     * @param organization
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateOrganizationById(CmOrganization organization) {
        CmOrganization parent = this.getOrganizationByOrgCode(organization.getParentId());
        organization.setOrgPath(parent.getOrgPath() + organization.getOrgId() + "/");
        cmOrganizationMapper.updateByPrimaryKeySelective(organization);
    }

    /**
     * 通过主键Id删除
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteOrganizationById(Long id) {
        cmOrganizationMapper.deleteByPrimaryKey(id);
    }

}
